﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.IO;
using System.IO.IsolatedStorage;
using System.Windows.Media.Imaging;
using System.Runtime.Serialization;
using System.Collections.Generic;
using Microsoft.Phone;
using PhotoUploader.Common;
using PhotoUploader.Common.Serialization;
using Microsoft.Phone.BackgroundTransfer;


namespace PhotoUploader.Models
{
    [DataContract]
    public class Picture : NotifyingObject, ISerializable
    {
        public string RequestId
        {
            get { return GetValue(() => RequestId); }
            set { SetValue(() => RequestId, value); }
        }

        public FileStatus FileStatus
        {
            get { return GetValue(() => FileStatus); }
            set
            {
                SetValue(() => FileStatus, value);
                NotifyPropertyChanged(() => IsActive);
            }
        }

        [IgnoreDataMember]
        public bool IsActive
        {
            get { return FileStatus == FileStatus.Active; }
        }

        [IgnoreDataMember]
        public TransferStatus TransferStatus
        {
            get { return GetValue(() => TransferStatus); }
            set { SetValue(() => TransferStatus, value); }
        }        

        [IgnoreDataMember]
        public long BytesSent
        {
            get { return GetValue(() => BytesSent); }
            set { SetValue(() => BytesSent, value); }
        }

        [IgnoreDataMember]
        public long TotalBytesToSend
        {
            get { return GetValue(() => TotalBytesToSend); }
            set { SetValue(() => TotalBytesToSend, value); }
        }


        [DataMember]
        public DateTime DateTaken
        {
            get { return GetValue(() => DateTaken); }
            set { SetValue(() => DateTaken, value); }
        }

        [IgnoreDataMember]
        public BitmapSource Source
        {
            get { return GetValue(() => Source); }
            private set { SetValue(() => Source, value); }
        }

        [DataMember]
        public byte[] Data
        {
            get;
            set;
        }

        [DataMember]
        public string FileName
        {
            get;
            set;
        }
        [IgnoreDataMember]
        public string NickName { get; set; }
        //[IgnoreDataMember]
        private bool isUpload;
        public bool IsUploaded
        {
            get { return isUpload; }
            set
            {
                isUpload = value;
                NotifyPropertyChanged("IsUploaded");
            }
        }
        public Picture()
        {

        }

        public Picture(string capturedFileName, Stream capturedImageStream)
        {
            Data = ReadImageBytes(capturedImageStream);
            DateTaken = DateTime.Now;
            FileName = Path.GetFileName(capturedFileName);            
        }

        private BitmapSource CreateBitmapSource()
        {
            if (Data == null) return null;            
            
            using (var stream = new MemoryStream(Data))
            {
                return PictureDecoder.DecodeJpeg(stream);
            }            
        }

        public void LoadSource()
        {
            if (Source == null)
                Source = CreateBitmapSource();
        }

        private byte[] ReadImageBytes(Stream imageStream)
        {
            byte[] imageBytes = new byte[imageStream.Length];
            imageStream.Read(imageBytes, 0, imageBytes.Length);
            return imageBytes;
        }

        public void Serialize(BinaryWriter writer)
        {
            writer.WriteString(RequestId);
            writer.Write((short)FileStatus);
            writer.Write(DateTaken.Ticks);
            writer.Write(Data.Length);
            writer.Write(Data);
            writer.WriteString(FileName);
        }

        public void Deserialize(BinaryReader reader)
        {
            RequestId = reader.ReadString();
            FileStatus = (FileStatus)reader.ReadInt16();
            DateTaken = new DateTime(reader.ReadInt64());
            int bytesCount = reader.ReadInt32();
            Data = reader.ReadBytes(bytesCount);
            FileName = reader.ReadString();
            if (FileStatus==FileStatus.Uploaded)
            {
                IsUploaded = true;
            }
            else
            {
                IsUploaded = false;
            }
        }       
    }
}
